package struts2.sample07.action;

import java.util.LinkedList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.config.Result;
import org.apache.struts2.config.Results;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.criterion.Expression;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.springframework.beans.BeanUtils;

import struts2.sample07.mapping.Devil;
import struts2.sample07.mapping.DevilType;

@Results({
	@Result(name="search", value="devil_search.jsp"),
	@Result(name="create", value="devil_create.jsp"),
	@Result(name="refer" , value="devil_refer.jsp"),
	@Result(name="update", value="devil_update.jsp")
})
public class DevilMasterAction {
	
	/** 検索条件：種族 */
	private int devilTypeId;

	/** 検索条件：名称 */
	private String devilName;

	/** 検索結果 */
	private List<Devil> searchResults;

	/** 種族のリスト */
	private List<DevilType> devilTypes;

	/** 悪魔 */
	private Devil devil;

	/** hibernateのセッションファクトリー */
	private SessionFactory sessionFactory;

	
	/**
	 * 検索の初期表示メソッド。
	 */
	public String searchInit() {
		loadDevilTypes();
		
		return "search";
	}
	
	
	
	/**
	 * 検索メソッド。
	 */
	@SuppressWarnings({ "unchecked" })
	public String search(){
		searchResults = new LinkedList();
		Session dbSession = sessionFactory.openSession();
		try{
			// 検索条件オブジェクト
			Criteria criteria = dbSession.createCriteria(Devil.class);
			// devilTypeIdが入力されてたら検索条件に追加
			if(devilTypeId != 0)
				criteria.add(Expression.eq("devilType.id", devilTypeId));
			// devilNameが入力されてたら検索条件に追加（部分一致）
			if(StringUtils.isNotEmpty(devilName))
				criteria.add(Expression.like(
						"name", devilName, MatchMode.ANYWHERE));
			// order by
			criteria.addOrder(Order.asc("id"));
			// 検索実行
			List<Devil> list = criteria.list();
			
			searchResults.addAll(list);
		}finally{
			dbSession.close();
		}
		
		loadDevilTypes();
		
		return "search";
	}



	/**
	 * 新規登録の初期表示メソッド
	 */
	public String createInit(){
		// プロパティを初期化
		devil = new Devil();

		loadDevilTypes();
		
		return "create";
	}

	
	
	/**
	 * 新規登録メソッド
	 */
	public String create(){
		Session dbSession = sessionFactory.openSession();
		try{
			Transaction transaction = dbSession.beginTransaction();
			dbSession.save(devil);
			transaction.commit();
		}finally{
			dbSession.close();
		}
		
		loadDevilTypes();
		
		return "create";
	}
	

	
	/**
	 * 更新の初期表示メソッド
	 */
	public String updateInit(){
		Session dbSession = sessionFactory.openSession();
		
		// データベースからデータを取得
		try{
			dbSession.load(devil, devil.getId());
		}finally{
			dbSession.close();
		}
		
		loadDevilTypes();
		
		return "update";
	}

	
	
	/**
	 * 更新メソッド
	 */
	public String update(){
		Session dbSession = sessionFactory.openSession();
		
		try{
			// トランザクション開始
			Transaction transaction = dbSession.beginTransaction();
			// データベースからエンティティを持ってくる
			Devil entity = (Devil)dbSession.load(
					Devil.class, devil.getId());
			// プロパティをコピー
			BeanUtils.copyProperties(devil, entity);
			// コミット
			transaction.commit();
		}finally{
			dbSession.close();
		}
		
		
		loadDevilTypes();
		
		return "update";
	}
	

	
	/**
	 * 削除メソッド
	 */
	public String delete(){
		Session dbSession = sessionFactory.openSession();
		
		try{
			// トランザクション開始
			Transaction transaction = dbSession.beginTransaction();
			// データベースからエンティティを持ってくる
			Devil entity = (Devil)dbSession.load(
					Devil.class, devil.getId());
			// 持ってきたエンティティを削除する
			dbSession.delete(entity);
			// コミット
			transaction.commit();
		}finally{
			dbSession.close();
		}
		
		return "search";
	}
	

	
	/**
	 * 参照メソッド
	 */
	public String refer(){
		Session dbSession = sessionFactory.openSession();
		
		// データベースから利用者情報を取得
		try{
			dbSession.load(devil, devil.getId());
		}finally{
			dbSession.close();
		}
		
		return "refer";
	}



	/**
	 * 悪魔種族をマスタから全部取得してdevilTypesに入れる。
	 */
	private void loadDevilTypes(){
		devilTypes = new LinkedList<DevilType>();
		Session dbSession = sessionFactory.openSession();
		
		// データベースから利用者情報を取得
		try{
			Criteria criteria = dbSession.createCriteria(DevilType.class);
			criteria.addOrder(Order.asc("id"));
			for(Object o: criteria.list())
				devilTypes.add((DevilType)o);
			
		}finally{
			dbSession.close();
		}
	}

	
	
	//
	// setterとgetter
	//
	
	public Devil getDevil() {
		return devil;
	}

	public void setDevil(Devil devil) {
		this.devil = devil;
	}

	public String getDevilName() {
		return devilName;
	}

	public void setDevilName(String devilName) {
		this.devilName = devilName;
	}

	public List getSearchResults() {
		return searchResults;
	}

	public void setSearchResults(List searchResults) {
		this.searchResults = searchResults;
	}

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	public List<DevilType> getDevilTypes() {
		return devilTypes;
	}

	public int getDevilTypeId() {
		return devilTypeId;
	}

	public void setDevilTypeId(int devilTypeId) {
		this.devilTypeId = devilTypeId;
	}

}
